package mapper

import (
	"context"
	"gorm.io/gorm"
	"mall/services/product/rpc/internal/domain/bo"
	"mall/services/product/rpc/internal/domain/do"
	"mall/services/product/rpc/internal/initialize/mysql"
	"mall/services/product/rpc/internal/mapper/entity"
)

var attrCategoryAllColumn = "attr_category_id, create_time, update_time, category_id, attr_id"

type AttrCategoryMapper struct {
	ctx context.Context
}

func NewAttrCategoryMapper(ctx context.Context) *AttrCategoryMapper {
	return &AttrCategoryMapper{
		ctx: ctx,
	}
}

func (m *AttrCategoryMapper) SelectCountCtx(db *gorm.DB, attrBO bo.AttrCategoryBO) (totalCount int64, err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrCategoryMapper#SelectCountCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})

	var total int64
	attrCategoryEntity := entity.AttrCategoryEntity{}
	tx = tx.Select(attrCategoryAllColumn).Table(attrCategoryEntity.TableName())
	m.getAllWhereSql(tx, attrBO)
	tx.Count(&total)
	return total, tx.Error
}

func (m *AttrCategoryMapper) SelectOneCtx(db *gorm.DB, attrBO bo.AttrCategoryBO) (returnEntity entity.AttrCategoryEntity, err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrCategoryMapper#SelectOneCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})
	attrEntity := entity.AttrCategoryEntity{}
	tx = tx.Select(attrCategoryAllColumn).Table(attrEntity.TableName())
	m.getAllWhereSql(tx, attrBO)
	tx.First(&attrEntity)
	if tx.Error.Error() == "record not found" {
		return attrEntity, nil
	}
	return attrEntity, tx.Error
}

func (m *AttrCategoryMapper) SelectListCtx(db *gorm.DB, attrBO bo.AttrCategoryBO) (returnEntity []entity.AttrCategoryEntity, err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrCategoryMapper#SelectListCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})
	var attrEntityArr []entity.AttrCategoryEntity
	tx = tx.Select(attrCategoryAllColumn).Table("attr_category")
	m.getAllWhereSql(tx, attrBO)
	tx = tx.Find(&attrEntityArr)
	return attrEntityArr, tx.Error
}

func (m *AttrCategoryMapper) getAllWhereSql(db *gorm.DB, attrBO bo.AttrCategoryBO) {
	if attrBO.AttrCategoryId > 0 {
		db.Where("attr_category_id = ?", attrBO.AttrCategoryId)
	}
	if attrBO.CategoryId > 0 {
		db.Where("category_id = ?", attrBO.CategoryId)
	}
	if attrBO.AttrId > 0 {
		db.Where("attr_id = ?", attrBO.AttrId)
	}
	if len(attrBO.StartTime) > 0 {
		db.Where("create_time = ?", attrBO.StartTime)
	}
	if len(attrBO.EndTime) > 0 {
		db.Where("create_time = ?", attrBO.EndTime)
	}
}

func (m *AttrCategoryMapper) InsertCtx(tx *gorm.DB, categoryEntity entity.AttrCategoryEntity) (
	attrCategoryId int64, err error) {

	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrCategoryMapper#InsertCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx = tx.Create(&categoryEntity)
	return categoryEntity.AttrCategoryId, tx.Error
}

func (m *AttrCategoryMapper) UpdateCtx(tx *gorm.DB, categoryEntity entity.AttrCategoryEntity) (err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrCategoryMapper#UpdateCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx = tx.Where("attr_category_id = ?", categoryEntity.AttrCategoryId).
		UpdateColumns(categoryEntity).Omit("attr_category_id")
	return tx.Error
}

func (m *AttrCategoryMapper) DeleteCtxByAttrId(tx *gorm.DB, attrIdArr []int64) (err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrCategoryMapper#DeleteCtxByAttrId")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	attrEntity := entity.AttrCategoryEntity{}
	tx = tx.Where("attr_id in ?", attrIdArr).Delete(&attrEntity)
	return tx.Error
}

func (m *AttrCategoryMapper) SelectCategoryByAttrId(engin *gorm.DB, attrId int64) (categoryDo do.AttrCategoryDO, err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrCategoryMapper#SelectCategoryByAttrId")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx := engin.Session(&gorm.Session{SkipDefaultTransaction: true})
	var returnDO do.AttrCategoryDO
	AllColumnJoin := "t2.category_id as category_id,attr_category.attr_category_id,attr_category.attr_id,t2.shop_id as shop_id," +
		"t2.parent_id as parent_id,t2.name as name,t2.desc as `desc`,t2.path as path," +
		"t2.status as status,t2.icon as icon,t2.img_url as img_url,t2.level as level,t2.seq as seq"
	tx = tx.Select(AllColumnJoin).
		Table("attr_category").
		Joins("left join category t2 on attr_category.category_id = t2.category_id").
		Where("attr_category.attr_id = ? ", attrId).Find(&returnDO)
	return returnDO, tx.Error
}

func (m *AttrCategoryMapper) SelectCategoryByAttrIdArr(engin *gorm.DB, attrIdArr []int64) (categoryDo []do.AttrCategoryDO, err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrCategoryMapper#SelectCategoryByAttrIdArr")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx := engin.Session(&gorm.Session{SkipDefaultTransaction: true})
	var returnDO []do.AttrCategoryDO
	AllColumnJoin := "t2.category_id as category_id,attr_category.attr_category_id,attr_category.attr_id,t2.shop_id as shop_id," +
		"t2.parent_id as parent_id,t2.name as name,t2.desc as `desc`,t2.path as path," +
		"t2.status as status,t2.icon as icon,t2.img_url as img_url,t2.level as level,t2.seq as seq"
	tx = tx.Select(AllColumnJoin).
		Table("attr_category").
		Joins("left join category t2 on attr_category.category_id = t2.category_id").
		Where("attr_category.attr_id in ?", attrIdArr).Find(&returnDO)
	return returnDO, tx.Error
}
